package com.zzyl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import com.zzyl.constant.UserCacheConstant;
import com.zzyl.utils.HttpStatus;
import com.zzyl.utils.UserThreadLocal;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.util.Set;
//TODO
@Aspect
@Component
public class PermissionAspect {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Around("@annotation(hasPermission)")
    public Object before(ProceedingJoinPoint pjp, HasPermission hasPermission) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        // 拿到Response
        HttpServletResponse response = attributes.getResponse();
        // 这个aop要做的事情是
        // 在执行添加了注解的方法之前
        // 先去redis中拿到user的label集合 如果注解上面的label包含在redis查出来的集合中 那么说明user就有对这个接口的访问方法
        // 否则就没有
        String[] perms = hasPermission.perms();
        if (ArrayUtil.isEmpty(perms)){
            return null;
        }
        // 拦截器已经把用户id保存到ThreadLocal中了
        Long userId = UserThreadLocal.getMgtUserId();
        Set<String> permsOfUserInRedis =
                stringRedisTemplate.opsForSet().members(UserCacheConstant.USER_RESOURCE + userId);
        if (CollectionUtil.isEmpty(permsOfUserInRedis)){
            response.setStatus(HttpStatus.FORBIDDEN);
            return null;
        }
        for (String perm : perms) {
            if (permsOfUserInRedis.contains(perm)){
                // 如果redis中的label列表包含注解上的label  就执行method
                pjp.proceed();
            }else {
                response.setStatus(HttpStatus.FORBIDDEN);
                return null;
            }
        }
        response.setStatus(HttpStatus.FORBIDDEN);
        return null;
    }
}